package com.lcy.mybatis.generator.plugin.element;

import org.apache.ibatis.annotations.Param;
import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.dom.java.FullyQualifiedJavaType;
import org.mybatis.generator.api.dom.java.Method;
import org.mybatis.generator.api.dom.java.Parameter;
import org.mybatis.generator.api.dom.xml.Attribute;
import org.mybatis.generator.api.dom.xml.TextElement;
import org.mybatis.generator.api.dom.xml.XmlElement;

import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * <p>创建时间：2017/5/4 16:51</p>
 *
 * @author 娄存银
 * @version 1.0
 */
public abstract class CustomerSqlElement {
    protected static final FullyQualifiedJavaType TYPE_STRING = new FullyQualifiedJavaType("String");
    protected static final FullyQualifiedJavaType TYPE_OBJECT = new FullyQualifiedJavaType("Object");
    protected static final FullyQualifiedJavaType TYPE_INTEGER = new FullyQualifiedJavaType("Integer");
    protected static final FullyQualifiedJavaType TYPE_STRING_OBJECT_MAP = new FullyQualifiedJavaType("Map<String,Object>");

    protected static final FullyQualifiedJavaType TYPE_LIST = new FullyQualifiedJavaType(List.class.getName());
    protected static final FullyQualifiedJavaType TYPE_MAP = new FullyQualifiedJavaType(Map.class.getName());

    protected static final String  COLUMN = "column";
    protected static final String  VALUE = "value";
    protected static final String  LIMIT = "limit";
    protected static final String  MAP = "map";

    protected static final String SELECT = "select";
    protected static final String DELETE = "delete";
    protected static final String ID = "id";
    protected static final String RESULT_MAP = "resultMap";
    protected static final String RESULT_TYPE = "resultType";

    protected IntrospectedTable table;
    protected XmlElement xmlElement;
    protected Method method;

    protected Set<FullyQualifiedJavaType> imports  = new HashSet<>();;

    public CustomerSqlElement(IntrospectedTable table) {
        this.table = table;
        initXmlElement();
        initMethod();

        imports.add(new FullyQualifiedJavaType(Param.class.getName()));
    }

    protected abstract void initXmlElement();
    protected abstract void initMethod();

    protected abstract String getId();
    protected abstract String getSql();

    protected XmlElement countElement(){
        XmlElement element = new XmlElement(SELECT);
        element.addAttribute(id());
        element.addAttribute(resultType("int"));
        element.addElement(new TextElement(String.format(getSql(),table.getFullyQualifiedTableNameAtRuntime())));
        return element;
    }

    protected XmlElement selectElement(){
        XmlElement element = new XmlElement(SELECT);
        element.addAttribute(id());
        element.addAttribute(resultMap());
        element.addElement(new TextElement(String.format(getSql(),table.getFullyQualifiedTableNameAtRuntime())));
        return element;
    }

    protected XmlElement deleteElement(){
        XmlElement element = new XmlElement(DELETE);
        element.addAttribute(id());
        element.addElement(new TextElement(String.format(getSql(),table.getFullyQualifiedTableNameAtRuntime())));
        return element;
    }

    public XmlElement getXmlElement() {
        return xmlElement;
    }

    protected Attribute resultMap(){
        return new Attribute(RESULT_MAP, "BaseResultMap");
    }

    protected Attribute resultType(String value){
        return new Attribute(RESULT_TYPE,value);
    }

    protected Attribute id(){
        return new Attribute(ID,getId());
    }

    public Method getMethod() {
        return method;
    }

    public void setTable(IntrospectedTable table) {
        this.table = table;
    }

    public IntrospectedTable getTable() {
        return table;
    }

    public Set<FullyQualifiedJavaType> getImports() {
        return imports;
    }

    protected FullyQualifiedJavaType modelListType(){
        return new FullyQualifiedJavaType("java.util.List<"+table.getBaseRecordType()+">");
    }

    protected FullyQualifiedJavaType modelType(){
        return new FullyQualifiedJavaType(table.getBaseRecordType());
    }

    protected String annotation(String name){
        return String.format("@Param(\"%s\")",name);
    }

}
